﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using System.Windows.Data;

namespace Relay.UI.Controls.Docking.Primitives {
    internal class GeometryButton : Button {
        #region Fields
        private bool _contentChanging = false;
        private bool _geometryChanging = false;
        #endregion

        #region Dependency Properties
        /// <summary>
        /// Identifies the Geometry dependency property.
        /// </summary>
        public static readonly DependencyProperty GeometryProperty = DependencyProperty.Register("Geometry",
            typeof(Geometry), typeof(GeometryButton), new FrameworkPropertyMetadata(
                new PropertyChangedCallback(OnGeometryChanged)));
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes the <see cref="GeometryButton"/> class.
        /// </summary>
        static GeometryButton() {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GeometryButton),
                new FrameworkPropertyMetadata(typeof(GeometryButton)));
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the geometry to show on the button.
        /// </summary>
        /// <value>The geometry.</value>
        public Geometry Geometry {
            get { return (Geometry)GetValue(GeometryProperty); }
            set { SetValue(GeometryProperty, value); }
        }
        #endregion

        #region Private Methods
        protected virtual void OnGeometryChanged(DependencyPropertyChangedEventArgs e) {
            if (_contentChanging) return;

            _geometryChanging = true;
            Image contentImage = new Image();
            GeometryDrawing drawing = new GeometryDrawing();
            Geometry geometry = e.NewValue as Geometry;

            if (geometry == null) {
                Content = null;
            } else {
                drawing.Geometry = geometry;
                drawing.Pen = new Pen();
                BindingOperations.SetBinding(drawing.Pen, Pen.BrushProperty,
                    new Binding() {
                        Source = this,
                        Path = new PropertyPath(ForegroundProperty)
                    });
            }

            contentImage.Source = new DrawingImage(drawing);
            contentImage.Stretch = Stretch.None;
            contentImage.SnapsToDevicePixels = false;

            Content = contentImage;
            _geometryChanging = false;
        }
        #endregion

        #region Overrides
        protected override void OnContentChanged(object oldContent, object newContent) {
            base.OnContentChanged(oldContent, newContent);

            if (_geometryChanging) return;

            _contentChanging = true;
            if (newContent is Geometry)
                Geometry = (Geometry)newContent;
            else
                Geometry = null;

            _contentChanging = false;
        }
        #endregion

        #region Event Handlers
        private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
            (d as GeometryButton).OnGeometryChanged(e);
        }
        #endregion
    }
}
